React'dagi useRef kuchini oching. To'g'ridan-to'g'ri DOM'ga kirish, o'zgaruvchan qiymatlarni saqlash va funksional komponentlar xatti-harakatini optimallashtirish kabi turli xil foydalanish holatlarini o'rganing.
React useRef: O'zgaruvchan qiymatlarni saqlash usullarini o'zlashtirish
useRef - bu React'dagi kuchli hook bo'lib, qiymatlar o'zgarganda qayta renderlashga sabab bo'lmasdan, renderlar orasida qiymatlarni saqlab qolish imkonini beradi. U ko'pincha DOM elementlariga to'g'ridan-to'g'ri kirish bilan bog'lanadi, lekin uning imkoniyatlari bundan ancha kengroq. Ushbu keng qamrovli qo'llanma useRefning turli xil foydalanish holatlarini chuqur o'rganib chiqadi va sizga yanada samarali va qo'llab-quvvatlanadigan React kodini yozish imkonini beradi.
useRef'ni tushunish: Faqat DOM'ga kirishdan ko'proq
Aslida, useRef o'zining .current xususiyati o'tkazilgan argument (initialValue) bilan ishga tushiriladigan o'zgaruvchan ref ob'ektini qaytaradi. Qaytarilgan ob'ekt komponentning butun hayoti davomida saqlanib qoladi. Eng muhimi, .current xususiyatini o'zgartirish qayta renderlashni ishga tushirmaydi. Bu useRef va useState o'rtasidagi asosiy farqdir.
DOM elementlariga kirish keng tarqalgan foydalanish holati bo'lsa-da, useRef yangilanganda qayta renderlashga sabab bo'lishi kerak bo'lmagan har qanday o'zgaruvchan qiymatni boshqarishda ajoyib natija ko'rsatadi. Bu uni quyidagi vazifalar uchun bebaho qiladi:
- Oldingi prop yoki state qiymatlarini saqlash.
- Hisoblagichlar yoki taymerlarni saqlash.
- Qayta renderlashga sabab bo'lmasdan fokus holatini kuzatish.
- Renderlar orasida saqlanishi kerak bo'lgan har qanday o'zgaruvchan qiymatni saqlash.
Asosiy foydalanish: DOM elementlariga kirish
Eng mashhur foydalanish holati - bu DOM elementlariga to'g'ridan-to'g'ri kirish. Bu kiritish maydoniga fokuslash, uning o'lchamlarini o'lchash yoki animatsiyalarni ishga tushirish kabi DOM tugunlari bilan imperativ tarzda o'zaro ishlashingiz kerak bo'lgan stsenariylar uchun foydalidir.
Misol: Kiritish maydoniga fokuslash
Komponent o'rnatilganda kiritish maydoniga fokuslash uchun useRef'dan qanday foydalanish mumkinligi quyida keltirilgan:
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const inputRef = useRef(null);
useEffect(() => {
// Focus the input field on mount
if (inputRef.current) {
inputRef.current.focus();
}
}, []); // Empty dependency array ensures this runs only once on mount
return (
<input type="text" ref={inputRef} placeholder="Enter text" />
);
}
export default MyComponent;
Tushuntirish:
- Biz
useRef(null)yordamida ref yaratamiz. Boshlang'ich qiymatnull, chunki komponent dastlab render qilinganda kiritish elementi hali mavjud emas. - Biz ref'ni
refprop'i yordamida kiritish elementiga biriktiramiz:ref={inputRef}. React kiritish elementi o'rnatilgandainputRef.current'ni avtomatik ravishda DOM tuguniga o'rnatadi. - Biz effekt faqat komponent o'rnatilgandan so'ng bir marta ishlashini ta'minlash uchun bo'sh bog'liqliklar massivi (
[]) bilanuseEffect'dan foydalanamiz. - Effekt ichida, biz
inputRef.currentmavjudligini tekshiramiz (element hali mavjud bo'lmasa, xatoliklarni oldini olish uchun) va keyin kiritish maydoniga fokuslash uchuninputRef.current.focus()'ni chaqiramiz.
DOM'ga kirishdan tashqari: O'zgaruvchan qiymatlarni boshqarish
useRef'ning haqiqiy kuchi uning qayta renderlashlarni ishga tushirmasdan renderlar orasida saqlanib qoladigan o'zgaruvchan qiymatlarni saqlash qobiliyatidadir. Bu funksional komponentlarda komponent xatti-harakatini optimallashtirish va holatni boshqarish uchun keng imkoniyatlar ochadi.
Misol: Oldingi Prop yoki State qiymatlarini saqlash
Ba'zan sizga prop yoki state o'zgaruvchisining oldingi qiymatiga kirish kerak bo'ladi. useRef keraksiz qayta renderlashlarni ishga tushirmasdan buni amalga oshirishning toza usulini taqdim etadi.
import React, { useRef, useEffect } from 'react';
function MyComponent({ value }) {
const previousValue = useRef(value);
useEffect(() => {
// Update the ref's .current property with the current value
previousValue.current = value;
}, [value]); // Effect runs whenever the 'value' prop changes
// Now you can access the previous value using previousValue.current
return (
<div>
Current value: {value}
<br />
Previous value: {previousValue.current}
</div>
);
}
export default MyComponent;
Tushuntirish:
- Biz
previousValueref'inivalueprop'ining boshlang'ich qiymati bilan ishga tushiramiz. - Biz
valueprop'i o'zgargandapreviousValue.currentxususiyatini yangilash uchunuseEffect'dan foydalanamiz. - Endi komponent ichida biz
previousValue.currentyordamidavalueprop'ining oldingi qiymatiga kira olamiz.
Foydalanish holati misoli: API javoblaridagi o'zgarishlarni kuzatish (Xalqaro stsenariy)
Tasavvur qiling, siz API'dan olingan valyuta kurslarini ko'rsatadigan boshqaruv panelini yaratayapsiz. API ma'lumotlar manbasiga qarab (masalan, Yevropa Markaziy Banki API'si va Janubi-Sharqiy Osiyo moliya instituti API'si) kurslarni turli formatlarda yoki har xil aniqlik darajasida qaytarishi mumkin. Siz useRef yordamida oldingi valyuta kursini kuzatib borishingiz va kurs oxirgi yangilanishdan beri oshgan yoki pasayganligini ko'rsatish uchun vizual indikator (masalan, yashil yuqoriga strelka yoki qizil pastga strelka) ko'rsatishingiz mumkin. Bu moliyaviy qarorlar uchun ushbu kurslarga tayanadigan xalqaro foydalanuvchilar uchun juda muhimdir.
Misol: Hisoblagichlar yoki Taymerlarni saqlash
useRef qayta renderlashlarni ishga tushirishi shart bo'lmagan hisoblagichlar yoki taymerlarni boshqarish uchun juda mos keladi. Masalan, siz undan tugma necha marta bosilganligini kuzatish yoki oddiy taymerni amalga oshirish uchun foydalanishingiz mumkin.
import React, { useRef, useState, useEffect } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const clickCount = useRef(0); // Initialize the ref with 0
const handleClick = () => {
clickCount.current++; // Increment the ref's .current property
setCount(clickCount.current); //Increment state which re-renders.
};
return (
<div>
<p>Button clicked: {count} times</p>
<button onClick={handleClick}>Click me</button>
</div>
);
}
export default MyComponent;
Tushuntirish:
- Biz
clickCountref'ini 0 qiymati bilan ishga tushiramiz. handleClickfunksiyasida bizclickCount.currentxususiyatini oshiramiz. Bu qayta renderlashni ishga tushirmaydi.- Biz shuningdek qayta renderlashni ishga tushiradigan 'count' holatini yangilaymiz.
Misol: Debounce funksiyasini amalga oshirish
Debouncing - bu funksiyaning bajarilish tezligini cheklash uchun ishlatiladigan texnika. U odatda foydalanuvchi yozayotganda haddan tashqari ko'p API chaqiruvlarini oldini olish uchun qidiruv kiritish maydonlarida qo'llaniladi. useRef debounce funksiyasida ishlatiladigan taymer ID'sini saqlash uchun ishlatilishi mumkin.
import React, { useState, useRef, useEffect } from 'react';
function MyComponent() {
const [searchTerm, setSearchTerm] = useState('');
const [results, setResults] = useState([]);
const timerRef = useRef(null); // Store the timer ID
const handleChange = (event) => {
const newSearchTerm = event.target.value;
setSearchTerm(newSearchTerm);
// Clear the previous timer if it exists
if (timerRef.current) {
clearTimeout(timerRef.current);
}
// Set a new timer
timerRef.current = setTimeout(() => {
// Simulate an API call
fetch(`https://api.example.com/search?q=${newSearchTerm}`)
.then(response => response.json())
.then(data => setResults(data.results));
}, 300); // Debounce for 300 milliseconds
};
return (
<div>
<input
type="text"
placeholder="Search..."
value={searchTerm}
onChange={handleChange}
/>
<ul>
{results.map(result => (
<li key={result.id}>{result.name}</li>
))}
</ul>
</div>
);
}
export default MyComponent;
Tushuntirish:
- Biz taymer ID'sini
timerRef'da saqlash uchunuseRef'dan foydalanamiz. handleChangefunksiyasida biz oldingi taymerni (agar mavjud bo'lsa)clearTimeout(timerRef.current)yordamida tozalaymiz.- Keyin biz
setTimeoutyordamida yangi taymer o'rnatamiz va taymer ID'sinitimerRef.current'da saqlaymiz. - API chaqiruvi faqat foydalanuvchi 300 millisekund davomida yozishni to'xtatgandan so'ng amalga oshiriladi.
Xalqarolashtirish masalalari: Turli tillarda ma'lumotlarni ko'rsatishni o'z ichiga olgan API chaqiruvlari bilan debouncingni amalga oshirayotganda, API'ngiz xalqarolashtirishni qo'llab-quvvatlashiga va ma'lumotlarni foydalanuvchining afzal ko'rgan tilida qaytarishiga ishonch hosil qiling. API so'rovlaringizda Accept-Language sarlavhasidan foydalanishni o'ylab ko'ring.
Misol: Qayta renderlashlarsiz Fokus Holatini Kuzatish
Siz useRef'dan elementning fokusda ekanligini qayta renderlashlarga sabab bo'lmasdan kuzatish uchun foydalanishingiz mumkin. Bu elementlarni ularning fokus holatiga qarab uslublash yoki maxsus fokus boshqaruv mantiqini amalga oshirish uchun foydali bo'lishi mumkin.
import React, { useRef, useState } from 'react';
function MyComponent() {
const [isFocused, setIsFocused] = useState(false);
const inputRef = useRef(null);
const handleFocus = () => {
setIsFocused(true);
};
const handleBlur = () => {
setIsFocused(false);
};
return (
<div>
<input
type="text"
ref={inputRef}
onFocus={handleFocus}
onBlur={handleBlur}
/>
<p>Input is focused: {isFocused ? 'Yes' : 'No'}</p>
</div>
);
}
export default MyComponent;
useRef va useState: To'g'ri vositani tanlash
Ish uchun to'g'ri vositani tanlash uchun useRef va useState o'rtasidagi asosiy farqlarni tushunish muhimdir.
| Xususiyat | useRef | useState |
|---|---|---|
| Qayta renderlashni ishga tushiradi | Yo'q | Ha |
| Maqsad | Qayta renderlashni ishga tushirishi kerak bo'lmagan o'zgaruvchan qiymatlarni saqlash. DOM elementlariga kirish. | Qayta renderlashni ishga tushirishi kerak bo'lgan holatni boshqarish. |
| Davomiylik | Qayta renderlar davomida saqlanadi. | Qayta renderlar davomida saqlanadi, lekin qiymat setter funksiyasi yordamida yangilanadi. |
Eng yaxshi amaliyotlar va umumiy xatolar
- Holatni to'g'ridan-to'g'ri o'zgartirmang:
useRefsizga qiymatlarni to'g'ridan-to'g'ri o'zgartirishga imkon bersa-da,useStatetomonidan boshqariladigan holat o'zgaruvchilarini to'g'ridan-to'g'ri o'zgartirishdan saqlaning. Holatni yangilash uchun har doimuseStatetomonidan taqdim etilgan setter funksiyasidan foydalaning. - Yon ta'sirlardan ehtiyot bo'ling: UI'ga ta'sir qiluvchi qiymatlarni boshqarish uchun
useRef'dan foydalanganda, potentsial yon ta'sirlardan ehtiyot bo'ling. Kodingiz oldindan aytib bo'ladigan tarzda ishlashiga va kutilmagan xatoliklarni keltirib chiqarmasligiga ishonch hosil qiling. - Renderlash mantiqi uchun
useRef'ga tayanmang:useRefo'zgarishlari qayta renderlashlarni ishga tushirmagani uchun, nima render qilinishi kerakligini aniqlash uchun uning qiymatlariga to'g'ridan-to'g'ri tayanmang. Renderlash mantiqini boshqarishi kerak bo'lgan qiymatlar uchunuseState'dan foydalaning. - Unumdorlik oqibatlarini hisobga oling:
useRefkeraksiz qayta renderlashlarning oldini olish orqali unumdorlikni optimallashtirishga yordam berishi mumkin bo'lsa-da, o'zgaruvchan qiymatlardan haddan tashqari ko'p foydalanish kodingizni tushunish va tuzatishni qiyinlashtirishi mumkinligini yodda tuting.
Ilg'or foydalanish holatlari va usullari
Komponent nusxalari bo'ylab qiymatlarni saqlash
useRef qiymatlarni *bitta* komponent nusxasining renderlari bo'ylab saqlasa-da, ba'zida qiymatning bir xil komponentning *turli* nusxalari bo'ylab saqlanishi kerak bo'ladi. Bu biroz boshqacha yondashuvni talab qiladi, ko'pincha modul darajasidagi o'zgaruvchini useRef bilan birgalikda qo'llashni o'z ichiga oladi.
// myComponent.js
let globalCounter = 0; // Module-level variable
import React, { useRef, useEffect } from 'react';
function MyComponent() {
const counterRef = useRef(globalCounter); // Initialize with the global value
useEffect(() => {
// Update the global counter whenever the ref changes
globalCounter = counterRef.current;
}, [counterRef.current]);
const increment = () => {
counterRef.current++;
//No setState needed, so no re-render
};
return (
<div>
<p>Counter: {counterRef.current}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
export default MyComponent;
Muhim mulohazalar: Ushbu usul global o'zgaruvchini kiritadi, shuning uchun potentsial yon ta'sirlar va poyga sharoitlaridan, ayniqsa murakkab ilovalarda, juda ehtiyot bo'ling. Agar qiymatni bir nechta komponentlar o'rtasida yanada nazoratli tarzda bo'lishish kerak bo'lsa, kontekst provayderidan foydalanish kabi muqobil yondashuvlarni ko'rib chiqing.
Xulosa: useRef kuchini ochish
useRef - bu React'dagi ko'p qirrali vosita bo'lib, u shunchaki DOM elementlariga kirishdan ancha uzoqqa boradi. Uning o'zgaruvchan qiymatlarni qayta renderlashlarni ishga tushirmasdan saqlash qobiliyatini tushunib, siz komponentlaringizni optimallashtirishingiz, holatni yanada samarali boshqarishingiz va yanada unumdor va qo'llab-quvvatlanadigan React ilovalarini yaratishingiz mumkin. Uni oqilona ishlatishni va har doim unumdorlik va kodning tushunarliligi o'rtasidagi potentsial murosasani hisobga olishni unutmang.
Ushbu qo'llanmada tasvirlangan usullarni o'zlashtirib, siz oddiy veb-ilova yoki murakkab korporativ tizim yaratayotganingizdan qat'i nazar, React loyihalaringizda useRef'ning to'liq salohiyatidan foydalanish uchun yaxshi qurollangan bo'lasiz. Global auditoriya uchun yaratayotganda xalqarolashtirish va qulaylikni hisobga olishni unutmang!